#pragma once
#include "Log.hpp"
#include <sys/epoll.h>
#include <unistd.h>
class Epoll
{
    const int size = 128;
    const int defaultfd = -1;

public:
    Epoll() : _fd(defaultfd)
    {
    }
    ~Epoll()
    {
        if (_fd != defaultfd)
            close(_fd);
    }
    void Create()
    {
        _fd = epoll_create(size);
        if (_fd == -1)
        {
            logMessage(ERROR, "epoll_create fail");
            exit(EPOLL_CREATE_ERR);
        }
        logMessage(NORMAL, "epoll_create success");
    }
    bool Control(int fd, int op, uint32_t event)
    {
        if (op == EPOLL_CTL_ADD)
        {
            struct epoll_event ev;
            ev.data.fd = fd;
            ev.events = event;
            int ret = epoll_ctl(_fd, op, fd, &ev);
            if (ret == -1)
            {
                logMessage(ERROR, "epoll_ctl(ADD) fail");
                return false;
            }
        }
        else if (op == EPOLL_CTL_MOD)
        {
            struct epoll_event ev;
            ev.data.fd = fd;
            ev.events = event;
            int ret = epoll_ctl(_fd, op, fd, &ev);
            if (ret == -1)
            {
                logMessage(ERROR, "epoll_ctl(MOD) fail");
                return false;
            }
        }
        else if (op == EPOLL_CTL_DEL)
        {
            int ret = epoll_ctl(_fd, op, fd, nullptr);
            if (ret == -1)
            {
                logMessage(ERROR, "epoll_ctl(DEL) fail");
                return false;
            }
        }
        else
        {
            logMessage(ERROR, "unknown error");
            return false;
        }
        return true;
    }
    int Wait(int num, struct epoll_event *events)
    {
        int ret = epoll_wait(_fd, events, num, -1);
        if (ret == -1)
        {
            logMessage(ERROR, "epoll_wait fail");
        }
        return ret;
    }

private:
    int _fd;
};